package learn.spring.persistence.support;

import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.DefaultReflectorFactory;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.ReflectorFactory;

import java.sql.Connection;
import java.util.Properties;

import static org.apache.ibatis.reflection.SystemMetaObject.DEFAULT_OBJECT_FACTORY;
import static org.apache.ibatis.reflection.SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY;

/**
 * @author suzheng
 * @version v.1.0
 */
@Intercepts(@Signature(type = StatementHandler.class, method ="prepare" , args ={Connection.class,Integer.class} ))
public class MyPageInterceptor implements Interceptor {
    private static final ReflectorFactory DEFAULT_REFLECTOR_FACTORY = new DefaultReflectorFactory();
    public Object intercept(Invocation invocation) throws Throwable {
        System.out.println("intercept");
        StatementHandler statementHandler = (StatementHandler) invocation.getTarget();

        MetaObject metaObject = MetaObject.forObject(statementHandler,
                DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY, DEFAULT_REFLECTOR_FACTORY);
        MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
        if(SqlCommandType.SELECT.equals(mappedStatement.getSqlCommandType())){
            if(mappedStatement.getId().contains("selectStr")){
                metaObject.setValue("delegate.boundSql.parameterObject.id",100);
                metaObject.setValue("delegate.rowBounds.offset",0);
                metaObject.setValue("delegate.rowBounds.limit",10);

            }

        }


        return invocation.proceed();
    }

    public Object plugin(Object target) {
        // 当目标类是StatementHandler类型时，才包装目标类，否者直接返回目标本身,减少目标被代理的次数
        if (target instanceof StatementHandler) {
            return Plugin.wrap(target, this);
        } else {
            return target;
        }
    }

    public void setProperties(Properties properties) {
        System.out.println("setProperties");

    }
}
